﻿using AutoMapper;
using Microsoft.AspNetCore.Identity;
using Microsoft.Extensions.Configuration;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Volo.Abp;
using Volo.Abp.Application.Services;
using Volo.Abp.Data;
using Volo.Abp.DependencyInjection;
using Volo.Abp.Domain.Repositories;
using Volo.Abp.Guids;
using Volo.Abp.Identity;
using Volo.Abp.Linq;
using Volo.Abp.Uow;
using Volo.Abp.Users;
using YaAppoint.Organizations.UserDepartments;
using YaAppoint.Response;
using YaAppoint.Users;

namespace YaAppoint.DepartmentUsers
{
    [RemoteService(isEnabled: false)]
    public class DepartmentUserAppService(IRepository<Department, Guid> departmentRepository,
                                          IConfiguration configuration,
                                          IRepository<UserDepartment,Guid> userDepartmentRepository,
                                          IRepository<IdentityUser,Guid> userRepository,
                                          IAsyncQueryableExecuter queryableExecuter,
                                          IGuidGenerator guidGenerator,
                                          IUnitOfWorkManager unitOfWorkManager,
                                          ICurrentUser currentUser,
                                          UserManager<IdentityUser> userManager,
                                          IMapper mapper) : ApplicationService, IDepartmentUserAppService, ITransientDependency
    {
        private readonly IRepository<Department, Guid> _departmentRepository = departmentRepository;
        private readonly IConfiguration _configuration = configuration;
        private readonly IRepository<UserDepartment, Guid> _userDepartmentRepository = userDepartmentRepository;
        private readonly IAsyncQueryableExecuter _queryableExecuter = queryableExecuter;
        private readonly UserManager<IdentityUser> _userManager = userManager;
        private readonly IRepository<IdentityUser, Guid> _userRepository = userRepository;
        private readonly IMapper _mapper=mapper;
        private readonly IGuidGenerator _guidGenerator = guidGenerator;
        private readonly ICurrentUser _currentUser = currentUser;
        private readonly IUnitOfWorkManager _unitOfWorkManager= unitOfWorkManager;

        /// <summary>
        /// 获取组织机构树数据
        /// </summary>
        /// <returns></returns>
        public async Task<BackJson> GetTreeDataAsync()
        {
            var list = await _departmentRepository.GetListAsync();
            
            var data = new
            { 
                name = _configuration["InstitutionName"],
                id = 1,
                icon = "fa fa-hospital",
                children = list.Select(x => new
                {
                    name = x.Name,
                    id = x.Id,
                    icon = "fa fa-building"
                })
            };

            var res = new List<object>();
            res.Add(data);


            return new BackJson()
            {
                code = 0,
                data = res
            };
        }

        /// <summary>
        /// 获取指定科室下用户
        /// </summary>
        public async Task<BackJson> GetListAsync(Guid id,string? filterName,int page,int pageSize)
        {
            var query = await _userDepartmentRepository.GetQueryableAsync();
            query = query.Where(x => x.DepartmentId == id && x.UserId!= _currentUser.Id);
            if (!string.IsNullOrEmpty(filterName))
            {
                query = query.Where(x => x.User.Name.Contains(filterName));
            }
            query = query.Skip(pageSize*(page-1)).Take(pageSize);
            var list = await _queryableExecuter.ToListAsync(query);
            foreach (var userDepartment in list)
            {
                if (userDepartment.User == null)
                { 
                   await _userDepartmentRepository.DeleteAsync(userDepartment);
                }
            }
            await  _unitOfWorkManager!.Current!.SaveChangesAsync();
            var newList = await _queryableExecuter.ToListAsync(query);
            var data = newList.Select(x => new UserDto
            {
                Id = x.User.Id,
                JobNumber=x.User.GetProperty<string>("JobNumber"),
                IdCardNumber=x.User.GetProperty<string>("IdCardNumber"),
                UserName = x.User.UserName,
                Name = x.User.Name,
                PhoneNumber=x.User.PhoneNumber,
                OuterCode = x.User.GetProperty<string>("OuterCode"),
                IsActive=x.User.IsActive
            });

            var res = new BackJson()
            {
                code = 0,
                data = data
            };

           return res;
        }

        /// <summary>
        ///  可以添加到特定科室的用户列表
        /// </summary>
        public async Task<BackJson> GetUsersForAdd(Guid id, string? filterName, int page, int pageSize)
        {
            var departmentUserList = await _userDepartmentRepository.GetListAsync(x=>x.DepartmentId ==id);
            var sysUserList = await _userRepository.GetListAsync();
            var list = new List<IdentityUser>();
            foreach (var user in sysUserList)
            {
                // 是否拥有 admin 角色
                var adminRole = await _userManager.IsInRoleAsync(user,"admin");

                // 是否已经在当前部门里
                var userInDep=departmentUserList.Find(x => x.User.Id == user.Id);

                if (userInDep == null && !adminRole)
                {
                    list.Add(user);
                }
            }
            var totalCount = list.Count;
            if (!string.IsNullOrEmpty(filterName))
            {
                list = list.Where(x => x.Name.Contains(filterName) || x.UserName.Contains(filterName)).ToList();         
            }
            list = list.Skip(pageSize * (page - 1)).Take(pageSize).ToList();


            return new BackJson()
            {
                code=0,
                data = new { 
                    users= _mapper.Map<List<IdentityUser>,List<UserDto>>(list),
                    totalCount=totalCount
                }
            };
        }

        /// <summary>
        /// 为科室创建用户
        /// </summary>
        public async Task<BackJson> CreateUserForDepartmentAsync(UserCreateDto dto, Guid depId)
        {
            var user = new IdentityUser(_guidGenerator.Create(), dto.UserName, dto.Email);
            user.Name = dto.Name;
            user.SetProperty<IdentityUser>("IsActive", dto.IsActive);
            user.SetProperty("NormalizedUserName", dto.UserName);
            user.SetProperty("LockoutEnabled",dto.LockoutEnabled);
            user.SetProperty("JobNumber", dto.JobNumber);
            user.SetProperty("PhoneNumber", dto.PhoneNumber);
            user.SetProperty("OuterCode", dto.OuterCode);
            user.SetProperty("IdCardNumber",dto.IdCardNumber);
            if (!string.IsNullOrWhiteSpace(_configuration["DefaultPwd"]))
            {
                dto.PasswordHash = _configuration!["DefaultPwd"]!;
            }

            var department = await _departmentRepository.GetAsync(depId);

            var res = new BackJson();
            var result = await _userManager.CreateAsync(user, dto.PasswordHash);
            if (result.Succeeded)
            {
                // 科室不存在
                if (department == null)
                {
                    throw new BusinessException(CustomErrorCodes.DepartmentNotExist);
                }

                var depUser = new UserDepartment()
                {
                    User = user,
                    UserId = user.Id,
                    DepartmentId = depId,
                    Department = department
                };

                await _userDepartmentRepository.InsertAsync(depUser);
                res.code = 0;
                res.msg = "用户创建成功，添加到科室成功。";
            }
            else
            {
                List<string> errors = new List<string>();
                foreach (var error in result.Errors)
                {
                    errors.Add(error.Description);
                }
                res.code = 1;
                res.msg = string.Join(", ", errors);
            }

            return res;
        }

        /// <summary>
        /// 向特定科室添加现有用户
        /// </summary>
        public async Task<BackJson> AddCurrentUserToDepartmentAsync(List<Guid> idList, Guid depId)
        {
            if (idList == null || idList.Count == 0)
            {
                throw new BusinessException(CustomErrorCodes.UserListIsEmpty);
            }

            var department = await _departmentRepository.GetAsync(depId);

            if (department == null)
            {
                throw new BusinessException(CustomErrorCodes.DepartmentNotExist);
            }

            foreach (var userId in idList)
            {
                var user = await _userRepository.GetAsync(userId);
                if (user == null)
                {
                    throw new BusinessException(CustomErrorCodes.UserNotExist);
                }
                var depUser= await _userDepartmentRepository.FirstOrDefaultAsync(x => x.UserId == userId && x.DepartmentId == depId);
                if (depUser == null)
                {
                    var newDepUser = new UserDepartment()
                    {
                        User = user,
                        UserId = userId,
                        Department = department,
                        DepartmentId = depId
                    };
                    await _userDepartmentRepository.InsertAsync(newDepUser);
                }
            }
            var res = new BackJson();
            res.code = 0;
            res.msg = "用户添加成功";
            return res;
        }

        /// <summary>
        /// 从指定科室移除指定用户(多个)
        /// </summary>
        public async Task<BackJson> RemoveUsersFromDepartmentAsync(List<Guid> idList, Guid depId)
        {
            var department = await _departmentRepository.FirstOrDefaultAsync(x=>x.Id==depId);
            if (department == null)
            {
                throw new BusinessException(CustomErrorCodes.DepartmentNotExist);
            }

            if (idList == null || idList.Count == 0)
            {
                throw new BusinessException(CustomErrorCodes.RemoveUserListIsEmpty);
            }

            foreach (var userId in idList)
            {
                await _userDepartmentRepository.DeleteAsync(x => x.UserId == userId && x.DepartmentId == depId);
            }
            
            return new BackJson()
            {
                code = 0,
                msg = "用户移除成功！"
            };
        }

        /// <summary>
        /// 根据用户ID，删除科室用户
        /// </summary>
        public async Task<BackJson> DeleteAllDeparmentUsersByUserIdAsync(Guid Id)
        {
            var idList = (await _userDepartmentRepository.GetListAsync(x => x.UserId == Id)).Select(x => x.Id);
            await _userDepartmentRepository.DeleteManyAsync(idList);
            return new BackJson()
            {
                code = 0
            };
        }
    }
}
